/**
 * by Chenbo 2011-8-4 18:25
 * deal with the xml content returned from web service invokation
 */
package com.xmu.edu.tisp.webservice;

import java.util.LinkedList;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.content.ContentValues;

import com.xmu.edu.tisp.database.Tables;

public class ServiceXmlParser {
	protected String xml;
	protected Document xmlDoc;

	public ServiceXmlParser(String xml) {
		this.xml = xml;
		try {
			xmlDoc = makeDocument();
		} catch (Exception ex) {
		}
	}
	
	public String getInterfaceName(){
		return xmlDoc.getDocumentElement().getTagName();
	}
	
	public Document getXmlDocument(){return xmlDoc;}
	public boolean isOK(){
		return xmlDoc!=null;
	}
	public String toString(){return xml;}

	protected Document makeDocument() throws Exception {
		java.io.InputStream is = new java.io.ByteArrayInputStream(xml.getBytes("GB2312"));
		org.w3c.dom.Document doc = javax.xml.parsers.DocumentBuilderFactory
				.newInstance().newDocumentBuilder().parse(is);
		return doc;
	}
	
	public ContentValues getFieldsFromArray(Node array){
		ContentValues cv = new ContentValues();
		NodeList items=array.getChildNodes();
		for(int i=0;i<items.getLength();++i){
			Node item=items.item(i);
			if(item.getNodeType()!=Node.ELEMENT_NODE || item.getFirstChild()==null) continue;
			//like: <user>aaa</user>
			cv.put(item.getNodeName(),item.getFirstChild().getNodeValue());
		}
		//detail is special tag
		if(cv.containsKey("detail")) cv.remove("detail");
		return cv;
	}
	
	public List<ContentValues> getArrays(int masterIndex){
		NodeList nodes=xmlDoc.getElementsByTagName("master").item(masterIndex).getChildNodes();
        List<ContentValues> list=new LinkedList<ContentValues>();
        for(int i=0;i<nodes.getLength();++i){
        	Node item=nodes.item(i);
        	if(item.getNodeName().toLowerCase().equals("array")){
        		list.add(getFieldsFromArray(item));
        	}
        }
        return list; 
	}
	
	public int getMasterCount(){
		return xmlDoc.getElementsByTagName("master").getLength();
	}
	
	public ContentValues getNodeAttributes(Node node){
		ContentValues cv=new ContentValues();
		if(!node.hasAttributes()) return cv;
		int k=node.getAttributes().getLength();
		for(int i=0;i<k;++i){
			Node item=node.getAttributes().item(i);
			cv.put(item.getNodeName(), item.getNodeValue());
		}
		return cv;
	}
	
	public ContentValues getMasterAttributes(int masterIndex){
		Node masterNode=xmlDoc.getElementsByTagName("master").item(masterIndex);
		return getNodeAttributes(masterNode);
	}
	
	public List<ContentValues> getArrays(){
		return getArrays(0);
	}
	
	public int getDetailCount(){
		return xmlDoc.getElementsByTagName("detail").getLength();
	}
	
	public ContentValues getDetailAttributes(int detailIndex){
		Node detailNode=xmlDoc.getElementsByTagName("detail").item(detailIndex);
		return getNodeAttributes(detailNode);
	}
	
	public List<String> getMasters(){
		List<String> list=new LinkedList<String>();
		int k=getMasterCount();
		for(int i=0;i<k;++i){
			list.add(getMasterAttributes(i).getAsString("type"));
		}
		return list;
	}
	
	public int getMasterIndexByName(String name){
		int k=getMasterCount();
		for(int i=0;i<k;++i){
			String type=getMasterAttributes(i).getAsString("type");
			if(type.equals(name)) return i;
		}
		return -1;
	}
	
	public List<String> getIds(String master){
		List<String> list=new LinkedList<String>();
		String pk=Tables.primaryKey(master);
		if(pk==null) return list;
		int masterIndex=getMasterIndexByName(master);
		if(masterIndex<0) return list;
		List<ContentValues> arrays=getArrays(masterIndex);
		for(ContentValues cv:arrays){
			list.add(cv.getAsString(pk));
		}
		return list;
	}
	
	public List<ContentValues> getDetailArrays(int detailIndex){
		Node detailNode=xmlDoc.getElementsByTagName("detail").item(detailIndex);
		NodeList nodes=detailNode.getChildNodes();
		List<ContentValues> list=new LinkedList<ContentValues>();
		for(int i=0;i<nodes.getLength();++i){
			Node node=nodes.item(i);
			if(node.getNodeName().toLowerCase().equals("array")){
				list.add(getFieldsFromArray(node));
			}
		}
		return list;
	}

}